package cn.com.dashihui.api.controller;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.aop.Duang;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.tx.Tx;

import cn.com.dashihui.api.base.BaseController;
import cn.com.dashihui.api.common.OrderCode;
import cn.com.dashihui.api.dao.Order;
import cn.com.dashihui.api.dao.OrderPayAPIRecord;
import cn.com.dashihui.api.service.OrderService;
import cn.com.dashihui.kit.DatetimeKit;
import cn.com.dashihui.kit.DoubleKit;
import cn.com.dashihui.pay.alipay.AlipayNotify;
import cn.com.dashihui.pay.wx.kit.UtilKit;
import cn.com.dashihui.pay.wx.response.NoticeResData;

/**
 * 各个支付平台支付结果处理回调通知处理类
 */
public class OrderPayNotifyController extends BaseController {
	private static Logger logger = Logger.getLogger(OrderPayNotifyController.class);
	OrderService orderService = Duang.duang(OrderService.class);

	/**
	 * 微信订单支付结果通知处理
	 */
	@Clear
	@Before(Tx.class)
	public void wx() {
		//获取支付平台发送的通知信息
		String returnContent = getRequestStr();
		//如果为空，则获取失败
		if(StrKit.isBlank(returnContent)){
			renderText("<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[获取支付结果通知信息失败！]]></return_msg></xml>");
			return;
		}
		//转换为对象
		NoticeResData noticeResData = (NoticeResData)UtilKit.getObjectFromXML(returnContent, NoticeResData.class);
		if(noticeResData!=null){
			//第一步验证，“返回状态码”为“SUCCESS”，且“业务结果”为“SUCCESS”
			if(noticeResData.getReturn_code().equalsIgnoreCase("SUCCESS") && noticeResData.getResult_code().equalsIgnoreCase("SUCCESS")){
				//第二步验证，通知过来的订单号是否存在
				String orderNum = noticeResData.getOut_trade_no();
				List<Order> orderList = orderService.getOrderListByMergerOrderNum(orderNum);
				//如果订单不存在，则直接返回SUCCESS，不处理
				if(orderList==null||orderList.size()<1){
					renderText("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[]]></return_msg></xml>");
					return;
				}
				//订单状态为已支付，则直接返回SUCCESS，不处理
				for(Order order : orderList){
					if(order.getInt("payType")==OrderCode.OrderPayType.ON_LINE&&order.getInt("payState")==OrderCode.OrderPayState.HAD_PAY){
						renderText("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[]]></return_msg></xml>");
						return;
					}
				}
				logger.info("微信支付结果通知："+returnContent);
				//记录接口记录
				new OrderPayAPIRecord()
					.set("orderNum",orderNum)
					.set("payMethod", OrderCode.OrderPayMethod.WEIXIN)
					.set("sendContent", null)
					.set("returnContent", returnContent)
					.set("flag", 2).save();
				//第三步验证，验证双方订单总金额是否一致
				double amount = 0;
				for(Order order : orderList){
					if(order.getInt("payType")==OrderCode.OrderPayType.ON_LINE){
						amount = DoubleKit.add(amount, order.getDouble("amount"));
					}
				}
				int amount_int = Double.valueOf(DoubleKit.mul(amount, 100)).intValue();
				int total_fee = Integer.valueOf(noticeResData.getTotal_fee());
				if(amount_int==total_fee){
					for(Order order : orderList){
						if(order.getInt("payType")==OrderCode.OrderPayType.ON_LINE){
							//修改订单状态为已支付，且记录微信交易订单号及支付时间
							order.set("tradeNo",noticeResData.getTransaction_id()).set("payState", OrderCode.OrderPayState.HAD_PAY).set("payDate", DatetimeKit.getFormatDate("yyyy-MM-dd HH:mm:ss")).update();
							orderService.log(order.getStr("orderNum"),OrderCode.OrderLogType.PAY,"用户", OrderCode.OrderLogType.PAY_ACTION, "订单支付成功，等待系统确认");
						}
					}
					renderText("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[]]></return_msg></xml>");
					return;
				}else{
					renderText("<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[订单金额校验错误]]></return_msg></xml>");
					return;
				}
			}
		}
	}
	
	/**
	 * 支付宝订单支付结果通知处理
	 * 注：
	 * 1.获取参数时如果有乱码，可使用new String(getPara("trade_status").getBytes("ISO-8859-1"),"UTF-8");
	 * 2.trade_status状态含义及建议处理
	 * TRADE_FINISHED（交易成功）：退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
	 * TRADE_SUCCESS（支付成功）：付款完成后，支付宝系统发送该交易状态通知
	 */
	@Clear
	@Before(Tx.class)
	public void alipay() {
		//获取支付宝POST过来反馈信息
		Map<String,String> params = new HashMap<String,String>();
		Map<String,String[]> requestParams = getParaMap();
		for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = iter.next();
			String[] values = requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
			params.put(name, valueStr);
		}
		//获取支付宝的通知返回参数，并验证签名是否正确
		if(AlipayNotify.verify(params)){
			logger.info("支付宝结果通知："+params.toString());
			//交易状态
			String trade_status = getPara("trade_status");
			//第一步验证，交易状态为“TRADE_SUCCESS”时表示支付成功
			if(trade_status.equals("TRADE_SUCCESS")){
				//支付宝交易号
				String trade_no = getPara("trade_no");
				//交易金额
				double total_fee = Double.parseDouble(getPara("total_fee"));
				//第二步验证，通知过来的订单号是否存在
				String orderNum = getPara("out_trade_no");
				List<Order> orderList = orderService.getOrderListByMergerOrderNum(orderNum);
				//如果订单不存在，则直接返回SUCCESS，不处理
				if(orderList==null||orderList.size()<1){
					renderText("success");
					return;
				}
				//订单状态为已支付，则直接返回SUCCESS，不处理
				for(Order order : orderList){
					if(order.getInt("payType")==OrderCode.OrderPayType.ON_LINE&&order.getInt("payState")==OrderCode.OrderPayState.HAD_PAY){
						renderText("success");
						return;
					}
				}
				//记录接口记录
				OrderPayAPIRecord record = new OrderPayAPIRecord()
					.set("orderNum",orderNum)
					.set("payMethod", OrderCode.OrderPayMethod.ALIPAY)
					.set("sendContent", null)
					.set("returnContent", params.toString())
					.set("flag", 2);
				record.save();
				//第三步验证，验证双方订单总金额是否一致
				double amount = 0;
				for(Order order : orderList){
					if(order.getInt("payType")==OrderCode.OrderPayType.ON_LINE){
						amount = DoubleKit.add(amount, order.getDouble("amount"));
					}
				}
				if(amount==total_fee){
					for(Order order : orderList){
						if(order.getInt("payType")==OrderCode.OrderPayType.ON_LINE){
							//修改订单状态为已支付，且记录支付宝交易订单号及支付时间
							order.set("tradeNo", trade_no).set("payState", OrderCode.OrderPayState.HAD_PAY).set("payDate", DatetimeKit.getFormatDate("yyyy-MM-dd HH:mm:ss")).update();
							orderService.log(order.getStr("orderNum"),OrderCode.OrderLogType.PAY,"用户", OrderCode.OrderLogType.PAY_ACTION, "订单支付成功，等待系统确认");
						}
					}
					renderText("success");
					return;
				}else{
					renderText("fail");
					return;
				}
			}
		}else{
			//验证失败
			renderText("fail");
		}
	}
	
	/**
	 * 从request中获取输入流
	 */
	private String getRequestStr(){
		try {
			HttpServletRequest request = this.getRequest();
			InputStream inStream = request.getInputStream();
			ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = inStream.read(buffer)) != -1) {
				outSteam.write(buffer, 0, len);
			}
			outSteam.close();
			inStream.close();
			return new String(outSteam.toByteArray(), "utf-8");
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("接收支付结果通知内容时出错！");
		}
		return null;
	}
}
